<?php
/**
 * 基础操作类
 * Created by PhpStorm.
 * User: zhangbing
 * Date: 2018/7/20
 * Time: 15:45
 */
namespace app\admin\controller;
use think\Controller;

class Base extends Controller{
    /**
     * @var 登录用户id
     */
    protected $id;

    /**
     * @var 请求参数
     */
    protected $params;

    /**
     * @var 请求路由
     */
    protected $route;

    /**
     * @var 日志
     */
    protected $logs;

    /**
     * @var 权限
     */
    protected $auth;

    /**
     * @var 用户信息
     */
    protected $info;

    /**
     * @var 数据库配置信息
     */
    protected $config;

    /**
     * @var bool 登录验证，true开启，false关闭
     */
    protected $needLogin = true;

    /**
     * @var bool 权限验证，true开启，false关闭
     */
    protected $needAuth  = true;

    /**
     * @var bool 用户状态验证，true开启，false关闭
     */
    protected $needCheck = true;

    /**
     * @var bool 验证失败是否抛出异常
     */
    protected $failException = false;

    /**
     * 从一个难以访问的属性读取数据的时候(1.无访问权限2.未初始化) __get() 方法被调用
     * @param string $name  属性名
     * @return mixed|\think\db\Query
     */
    public function __get($name){
        return $this->$name = \think\Db::name($name);
    }

    /**
     * 向一个难以访问的属性赋值的时候(1.无访问权限2.未初始化) __set() 方法被调用
     * @param string $name 属性名
     * @param string $value  属性值
     */
    public function __set($name, $value){
        $this->$name = $value;
    }

    protected function _initialize(){
        $this->id     = session('login');  // 获取登录id
        $this->params = array_filter( input('param.') );  // 获取入参,并过滤空参数
        $this->route  = strtolower( '/'.$this->request->module().'/'.$this->request->controller().'/'.$this->request->action() );
        $this->config = get_config();

        self::_constant();     // 常量定义
        self::_loginValid();   // 登录验证
        self::_statusValid();  // 状态验证
        self::_layout();       // 渲染模板

        if ( $this->id != \Param::GROUP_ADMIN ) { //超管不做权限验证
            $this->auth = Auth::instance();  // 权限验证
            $this->auth->_onoff = $this->needAuth;
            if ( $this->auth->check($this->route, $this->id) ) return true;
            if ( IS_POST ) return error(-1, '抱歉，您不具备该权限!');  // ajax返回
            else $this->error('抱歉，您不具备该权限!');  // 跳转返回
            exit;
        }
    }

    /**
     * 常量定义
     */
    private function _constant(){
        !defined('IS_POST') && define('IS_POST', $this->request->isPost()); // 定义是否POST请求
        !defined('IS_AJAX') && define('IS_AJAX', $this->request->isAjax()); // 定义是否AJAX请求
    }

    /**
     * 登陆验证
     */
    private function _loginValid(){
        if ( $this->needLogin ) {   // 登录验证
            if ( !$this->id ) $this->redirect('login/login');
            // 获取当前用户及分组信息
            self::_user();
            $session_end = session('session.end_time');  // 获取session结束时间
            if ($session_end < time()) {
                session('login', null);
                $this->redirect('login/login');
            }
        }
    }

    /**
     * 用户状态验证
     * @return \Illuminate\Http\JsonResponse|string
     */
    private function _statusValid(){
        if ( $this->needCheck) {   // 用户状态验证，通过则返回用户信息
            if ( $this->info['status'] != \Param::STATUS_ON ) {
                session('login', null);
                if (IS_POST) return error(-2, '抱歉，您已被禁用！');  // ajax返回
                else $this->error('抱歉，您已被禁用！');  // 跳转返回
                exit;
            }
        }
    }

    /**
     * 渲染模板
     */
    private function _layout(){
        $nav = self::_nav();
        $this->assign([
            'nav'          => json_encode($nav),  //渲染导航栏
            'user'         => json_encode($this->info), //渲染当前用户及分组信息
            'auth'         => json_encode(self::_menu()), //渲染菜单栏
            'active_index' => $nav ? $nav['pid'].'-'.$nav['id'] : '0',  // 当前激活菜单
            'menu_opened'  => $nav['pid'],  //当前打开菜单
            'config'       => $this->config,
            'route'        => $this->route,
        ]);
    }

    /**
     * 获取当前用户及分组信息
     * @return mixed
     */
    protected function _user(){
        $info = $this->joinOne(
            $this->admin,
            [['auth_group_access b','a.id = b.uid','inner'],['auth_group c','b.group_id = c.id','inner']],
            ['a.id'=>$this->id],
            'a.*,b.group_id,c.pid,c.group_name,c.auth_ids'
        );
        $info['last_login_ip'] = long2ip($info['last_login_ip']);
        $info['last_login_time'] = date('Y-m-d H:i:s', ($info['last_login_time']));
        $info['create_time'] = date('Y-m-d H:i:s', ($info['create_time']));
        $info['update_time'] = date('Y-m-d H:i:s', ($info['update_time']));
        $this->info = $info;
    }

    /**
     * 获取当前用户的所有权限
     * @return mixed
     */
    protected function _auth(){
        // 超级管理员至高无上
        $where = $this->id == \Param::GROUP_ADMIN
            ? ['status'=>\Param::STATUS_ON]
            : ['id'=>['in', $this->info['auth_ids']], 'status'=>\Param::STATUS_ON];
        // 获取当前用户具备的权限
        $auth_rules  = $this->getList($this->auth_rule, $where,'','sort desc');
        return $auth_rules;
    }

    /**
     * 组合菜单
     */
    private function _menu(){
        $auth_rules = self::_auth();

        $auth = array();
        $sub  = array();
        foreach($auth_rules as $k=>$v){
            if ($v['pid'] == 0) {
                $auth[] = $v;
            } else {
                $sub[] = $v;
            }
        }
        // 组合权限菜单
        foreach($auth as $k=>$v){
            foreach($sub as $k1=>$v1){
                if($v['id'] == $v1['pid']){
                    $auth[$k]['sub'][]  = $v1;
                }
            }
        }
        return $auth;
    }

    /**
     * 面包屑导航
     * @return mixed
     */
    private function _nav(){
        $nav = $this->joinOne(
            $this->auth_rule,
            [['auth_rule b','a.pid = b.id','inner']],
            ['a.auth_rule'=>$this->route],
            'a.id,a.pid,a.rule_name son_rule,a.desc,b.rule_name parent_rule'
        );
        if ($nav && $nav['desc']) {
            $nav['desc'] = explode(';', $nav['desc']);
        }
        return $nav;
    }

    /**
     * 批量修改
     * @param $list
     * @param $table
     * @param $then
     * @param $when
     * @param $where
     * @return int
     */
    protected function updateBatch($list, $table, $then, $when, $where){
        $sql = "UPDATE `{$table}` SET `{$then}` = CASE `{$when}` ";
        foreach ($list as $k=>$v) {
            $sql .= sprintf("WHEN %s THEN %s ", $v[$when], $v[$then]);
        }
        $sql .= "END WHERE {$where}";
        $res = \think\Db::execute($sql);
        return $res;
    }

    /**
     * 返回多条记录
     * @param $obj object 对象模型
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $limit
     * @param string $group
     * @return mixed
     */
    protected function getList($obj, $where='',$field='*',$order='',$limit='',$group=''){
        return $obj->field($field)->where($where)->group($group)->order($order)->limit($limit)->select();
    }

    /**
     * 返回一条记录
     * @param $obj
     * @param $where
     * @param string $field
     * @return mixed
     */
    protected function getRow($obj, $where, $field='*'){
        return is_numeric($where) ? $obj->field($field)->find($where) : $obj->field($field)->where($where)->find();
    }

    /**
     * 聚合函数 统计
     * @param $obj
     * @param $where
     * @return mixed
     */
    protected function getCount($obj, $where){
        return $obj->where($where)->count();
    }

    /**
     * 返回某一列数据
     * @param $obj
     * @param $where
     * @param $field
     * @param string $order
     * @return mixed
     */
    protected function getColumn($obj, $where, $field, $order=''){
        return $obj->where($where)->order($order)->column($field);
    }

    /**
     * 连表查询单条信息
     * @param $obj
     * @param $join
     * @param $where
     * @param string $field
     * @return mixed
     */
    protected function joinOne($obj, $join, $where, $field='*'){
        return $obj->alias('a')->field($field)->join($join)->where($where)->find();
    }

    /**
     * 连表查询多条信息
     * @param $obj
     * @param $join
     * @param string $where
     * @param string $field
     * @param string $order
     * @param string $limit
     * @param string $group
     * @return mixed
     */
    public function joinMany($obj, $join, $where='',$field='*', $order='', $limit='', $group=''){
        return $obj->alias('a')->distinct(true)->field($field)->join($join)->where($where)->group($group)->order($order)->limit($limit)->select();
    }

    /**
     * 更新某个字段的值
     * @param $obj
     * @param $where
     * @param $field
     * @param string $value
     * @return mixed
     */
    protected function setValue($obj, $where, $field, $value){
        return $obj->where($where)->setField($field, $value);
    }

    /**
     * 返回某个字段的值
     * @param $obj
     * @param $where
     * @param $field
     * @return mixed
     */
    protected function getValue($obj, $where, $field){
        return $obj->where($where)->value($field);
    }
}